Skip to content

[SSF-180] - Automated Emails 2 Implementation#154

Open
swarkewalia wants to merge 2 commits intomainfrom
sk/SSF-180-automated-emails
Open

[SSF-180] - Automated Emails 2 Implementation#154
swarkewalia wants to merge 2 commits intomainfrom
sk/SSF-180-automated-emails

Conversation

@swarkewalia
Copy link
Copy Markdown

ℹ️ Issue

Closes SSF-180

📝 Description

Implemented email templates for:

  • FM Recurring Donation Reminder
  • Tracking link becomes available
  • Pantry Confirms Order Delivery
    All links use configurable domain variable

✔️ Verification

BEFORE TESTING: Add 2 new environment variables:

AWS_SES_SENDER_EMAIL (set this to one of your emails, this will be the address that sends the emails for you to verify)
SEND_AUTOMATED_EMAILS (switch this to true to turn on Cognito account creation and email sending permissions)
Add your email that you put in the AWS_SES_SENDER_EMAIL into the following AWS SES Identities: https://us-east-2.console.aws.amazon.com/ses/home?region=us-east-2#/identities

Tested each workflow to ensure the proper sender, subject, message, attachments were all there.

Same testing as #127

🏕️ (Optional) Future Work / Notes

emails go to spam :(

Copy link
Copy Markdown

@Juwang110 Juwang110 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sam-schu Should we be adding tests for the new email functionality like in #127

expected donation.
</p>
<p>
Tracking Link: <a href="${params.trackingLink}">${params.trackingLink}</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make "Tracking Link" bold

recurring donations make a meaningful and consistent impact for the communities we serve.
</p>
<p>Best regards,<br />The Securing Safe Food Team</p>
`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add the additional link? The email template doc says:

"Additional Content (Links, Images, etc)
Link to make new donation (otherwise just the login link)"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, sorry the details weren't in the ticket, but we should use the resubmitDonationId query param in the link to navigate to the particular donation to resubmit - e.g., the end of the link might look like ?resubmitDonationId=5 if we're sending the reminder for donation 5 (the query param will not do anything yet but is being implemented this week in the frontend)

Tracking Link: <a href="${params.trackingLink}">${params.trackingLink}</a>
</p>
<p>
You can use the tracking link above to monitor your shipment, or <a href="${EMAIL_REDIRECT_URL}/login">log into your portal</a> for full order details and updates.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this should be a link for the "log into your portal", @sam-schu can you clarify?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't hurt!

.execute();
}

// Updated confirmDelivery()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we need this


await this.requestsService.updateRequestStatus(order.requestId);

const { subject, bodyHTML } = emailTemplates.pantryConfirmsOrderDelivery({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Dalton's PR, he wrapped this logic in a try catch with an InternalServerErrorException, can we mimic that pattern here for consistency

if (fmEmails.length > 0) {
await this.emailsService.sendEmails(fmEmails, cs, cb);
}
} catch (e) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

].filter((e): e is string => e !== null);

if (fmEmails.length > 0) {
await this.emailsService.sendEmails(fmEmails, cs, cb);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename cs and cb to subject and bodyHTML for consistency

});

try {
const fmEmails = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be sending the email to the FMRep's contact email as well as maybe this secondary one? @sam-schu could you confirm?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should only be the representative's email!


try {
const fmEmails = [
donation.foodManufacturer.secondaryContactEmail,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about email

volunteerEmail: order.assignee.email,
});

const pantryEmails = [order.request.pantry.secondaryContactEmail].filter(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here about email, I could be wrong though

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes should be pantry representative email again!

Copy link
Copy Markdown
Collaborator

@sam-schu sam-schu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on Justin's comment for adding tests!

});

try {
const fmEmails = [
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should only be the representative's email!

recurring donations make a meaningful and consistent impact for the communities we serve.
</p>
<p>Best regards,<br />The Securing Safe Food Team</p>
`,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, sorry the details weren't in the ticket, but we should use the resubmitDonationId query param in the link to navigate to the particular donation to resubmit - e.g., the end of the link might look like ?resubmitDonationId=5 if we're sending the reminder for donation 5 (the query param will not do anything yet but is being implemented this week in the frontend)

if (fmEmails.length > 0) {
await this.emailsService.sendEmails(fmEmails, subject, bodyHTML);
}
} catch (e) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should throw an exception for email failures in this method, continue/break as the existing placeholder code had is the right thing to do for control flow. The service functions Dalton updated were called by controller methods and the email sending was the last thing done in the function, so the exception would serve to let the caller know that the email failed but wouldn't affect the functionality otherwise because the function was going to return anyway. This function is called by a cron job to send all the reminders for a day, and we want to continue trying to send emails for other donations even if one of them fails. It would be good to log a warning in this case though

volunteerEmail: order.assignee.email,
});

const pantryEmails = [order.request.pantry.secondaryContactEmail].filter(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes should be pantry representative email again!

order.status = OrderStatus.SHIPPED;
order.shippedAt = new Date();

const { subject, bodyHTML } = emailTemplates.trackingLinkAvailable({
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we will be throwing an exception if the email fails, we should make sure to send the email after saving the order to the database so we still update the order even if the email fails

Tracking Link: <a href="${params.trackingLink}">${params.trackingLink}</a>
</p>
<p>
You can use the tracking link above to monitor your shipment, or <a href="${EMAIL_REDIRECT_URL}/login">log into your portal</a> for full order details and updates.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't hurt!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants